package android.FiltrosJava;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;

public class Ripple extends AbstractImageBasic {
	protected int WATERSIZE = 256;
	protected int WATERSIZE2 = 2 * WATERSIZE;
	protected int dripRadius = 12;
	protected int [] wbuffer;
	
	protected void setDisplay(BufferedImage src, BufferedImage dst, int[] ReadBuffer, int[] WriteBuffer){
		int cnt;
		float R, G, B;
		int temp, xoff, yoff;
		
		for (int i = 0; i < WATERSIZE*WATERSIZE; i++){
			temp  = ReadBuffer[i];
			ReadBuffer[i] = WriteBuffer[i];
			WriteBuffer[i] = temp;
		}
		
		cnt = 0;

		for (int j = 0; j < WATERSIZE; j++){
			for (int i = 0; i < WATERSIZE; i++){
				xoff = i;
				if ((i > 0) & (i < WATERSIZE-1)){
					xoff = xoff - ReadBuffer[cnt-1];
					xoff = xoff + ReadBuffer[cnt+1];
				}

				yoff = j;
				if ((j > 0) & (j < WATERSIZE-1)){
					yoff = yoff - ReadBuffer[cnt - WATERSIZE];
					yoff = yoff + ReadBuffer[cnt + WATERSIZE];
				}

				// Clamp the offset to actual picture range
				if (xoff < 0)
					xoff = 0;
				else
					if (xoff >= WATERSIZE)
						xoff = WATERSIZE - 1;

				if (yoff < 0)
					yoff = 0;
				else
					if (yoff >= WATERSIZE)
						yoff = WATERSIZE - 1;


				/*
				R = im(xoff,yoff,0);
				G = im(xoff,yoff,1);
				B = im(xoff,yoff,2);

				R =  (R + (float) (ReadBuffer[cnt]));
				G =  (G + (float) (ReadBuffer[cnt]));
				B =  (B + (float) (ReadBuffer[cnt]));

				// Clamp color to the valid range
				R = delimitaCor(R);
				G = delimitaCor(G);
				B = delimitaCor(B);
				
				im_dest(i,j,0) = R;
				im_dest(i,j,1) = G;
				im_dest(i,j,2) = B;

				cnt++;
				*/
			}
		}
	}

    public BufferedImage applyFilter(BufferedImage src){
    	BufferedImage dst = createCompatibleDestImage(src);
		
		int dimX = src.getWidth();
		int dimY = src.getHeight();		
		WritableRaster raster_src = src.getRaster();
    	WritableRaster raster_dst = dst.getRaster();
    	int[] imageData = new int[raster_src.getNumBands()];    	    
    	    	
    	for (int y = 0; y < dimY-1; y++){
    		for (int x = 0; x < dimX-1; x++){
    			raster_src.getPixel(x,y,imageData);
    	    	
			}
		}
		
		return dst;	
    }
    
    protected void makeDrip(int x, int y, int depth){
    	int distanceSquared;
    	float finalDepth;

    	int radiusSquared = (int) (dripRadius * dripRadius);	

    	for (int j = (y - dripRadius); j < (y + dripRadius); j++){
    		for (int i = (x - dripRadius); i <= (x + dripRadius); i++){
    			if ((i >= 0) && (i < WATERSIZE) && (j >= 0) && (j < WATERSIZE)){
    				distanceSquared = (int)(((i - x) * (i - x)) + ((j - y) * (j - y)));

    				if (distanceSquared < radiusSquared){
    					finalDepth = (float)(depth * ((float)dripRadius - Math.sqrt(distanceSquared))/dripRadius);
    					if (finalDepth > 127.0f)
    						finalDepth = 127.0f;
    					else
    						if (finalDepth < -127.0f)					
    							finalDepth = -127.0f;

    					OutBuffer(wbuffer, i, j, (int) Math.round(finalDepth));
    				}
    			}
    		}		
    	}    	
    }
    
    protected void OutBuffer(int[] buffer, int x, int y, int value){
    	buffer[y * WATERSIZE + x] = value;
    }//escreve no buffer...

    protected int InBuffer(int[] buffer, int x, int y){
    	return buffer[y * WATERSIZE + x];
    }//le do buffer
        
    protected void processWater(int[] ReadBuffer, int[] WriteBuffer, double dampingFactor){
    	int k;
    	float value;

    	for (int j = 2; j < WATERSIZE-2; j++){
    		for (int i = 2; i < WATERSIZE-2; i++){
    			k  = (int) (j * WATERSIZE);

    			value = (float) (InBuffer(ReadBuffer, i-2, j  )  +
    							 InBuffer(ReadBuffer, i+2, j  )  +
    							 InBuffer(ReadBuffer, i  , j-2)  +
    							 InBuffer(ReadBuffer, i  , j+2)  +
    							 InBuffer(ReadBuffer, i-1, j  )  +
    							 InBuffer(ReadBuffer, i+1, j  )  +
    							 InBuffer(ReadBuffer, i  , j-1)  +
    							 InBuffer(ReadBuffer, i  , j+1)  +
    							 InBuffer(ReadBuffer, i-1, j-1)  +
    							 InBuffer(ReadBuffer, i+1, j-1)  +
    							 InBuffer(ReadBuffer, i-1, j+1)  +
    							 InBuffer(ReadBuffer, i+1, j+1));

    			value = (float)(value / 6.0);//  Average * 2
    			value = (value - (float)InBuffer(WriteBuffer, i,j));
    			
    			// Values for damping from 0.0001 to 0.0400 look pretty good
    			value = (float) (value - (value * dampingFactor));

    			// Range check problem detected by Delphi
    			if (value > 127.0f)
    				value = 127.0f;
    			else
    				if (value < -127.0f)
    					value = -127.0f;

    			OutBuffer(WriteBuffer, i, j, (int) Math.round(value));
    		}
    	}	
    }        
}